<!-- eslint-disable max-lines -->
<template>
  <span class="component-customerDialog" @click="show">
    <slot></slot>
    <div
      v-if="minimizable"
      v-show="minimizeSign"
      ref="minimizeBlock"
      class="minimizeBlock"
      @click="stopPropagation($event)"
    >
      {{ title }}
      <div
        class="el-icon-copy-document minimize-button"
        style="right: 27px;"
        @click="resizeMinimize"
      ></div>
      <div class="el-icon-close minimize-button" @click="closeMinimize"></div>
    </div>
    <!-- v-show="!minimizable || (minimizable && !minimizeSign)" -->
    <el-dialog
      v-if="visible || (minimizable && minimizeSign)"
      v-penetrate="modalPenetrate"
      ref="dialog"
      class="m-dialog--comDialog"
      :custom-class="className"
      :title="title"
      :visible="!minimizable || (minimizable && !minimizeSign)"
      append-to-body
      :width="width"
      :before-close="willClose"
      :top="top"
      :modal="modal"
      :close-on-click-modal="closeOnClickModal"
      :close-on-press-escape="closeOnPressEscape"
      :show-close="showClose"
    >
    <!-- @close="close" 不监听dialog的关闭事件，否则在函数式打开弹窗时的最小化会出现意外情况，这里只在手动点击时(willClose)判断是否要对外抛出close事件 -->
      <div
        v-if="autoScroll"
        class="m-scroll--comDialog hiddenX light-little-scroll"
        :style="scrollStyle"
      >
        <component
          :is="component"
          v-if="showSelfComponent"
          @closeDialog="close"
        ></component>
        <slot name="body" :close="close"></slot>
      </div>
      <div v-else :style="scrollStyle" class="body_wrapper">
        <slot name="body" :close="close"></slot>
      </div>
      <template slot="footer">
        <slot name="footer"></slot>
      </template>
    </el-dialog>
    <span v-show="false">{{ updateDrag() }}{{ updateMinimize() }}</span>
  </span>
</template>

<script>
import _ from "lodash";
import { Dragable } from "@utils/dragable";
const isFunction = f => typeof f === "function";
export default {
  name: "com-dialog",
  props: {
    modal: {
      type: Boolean,
      default: true,
    },
    modalPenetrate: {
      type: Boolean, // 蒙层是否可点击穿透
      default: false,
    },
    fullscreen: {
      type: Boolean,
      default: true,
    },
    width: {
        type: String,
        default: "50%"
    },
    top: {
        type: String,
        default: "5vh"
    },
    height: {
        type: String // vh,px, 'auto' 1.不传默认75vh，2.传auto：自适，3.高度
    },
    className: {
        type: String,
        default: "newDialogClass",
    },
    component: {
        // 加载哪个组件,可传全局组件或者通过slot
        type: String
    },
    title: {
        // 弹窗标题
        type: String,
        default: "详情"
    },
    beforeClose: {
        type: Function
    },
    beforeShow: {
        type: Function
    },
    scrollClassName: String,
    closeOnClickModal: { type: Boolean, default: false },
    closeOnPressEscape: { type: Boolean, default: true },
    showClose: { type: Boolean, default: true },
    autoScroll: { type: Boolean, default: true },
    autoShow: {
        type: Boolean,
        default: false
    },
    dragable: {
        type: Boolean,
        default: true
    },
    minimizable: {
      type: Boolean,
      default: false
    }
  },
  data() {
      return {
          visible: false,
          minimizeSign: false,
          showSelfComponent: false,
          // drawSet: {}
          windowDragable: new Dragable(),
          minimizeDragable: new Dragable(),
      };
  },
  computed: {
    scrollStyle() {
      let ret = {};
      if (this.height) {
        ret.height = this.height;
      }
      return ret;
    }
  },
  created() {
    if (this.component && !this.$slots.body) {
      this.showSelfComponent = true;
    }
  },
  mounted() {
    if (this.autoShow) {
      this.$nextTick(() => {
          this.show();
      });
    }
  },
  methods: {
    stopPropagation(e) {
      e.stopPropagation();
    },
    show() {
      if (isFunction(this.beforeShow) && !this.beforeShow()) {
        return;
      }
      this.minimizeSign = false,
      this.visible = true;
      this.$emit('show');
    },
    close() {
      this.visible = false;
      this.$emit("close");
      if(!this.minimizeSign) {
        this.lastWindowOffset = null;
      }
    },

    willClose(done) {
      const next = () => {
        done();
        setTimeout(() => this.close())
      }
      if (isFunction(this.beforeClose)) {
        return this.beforeClose(next);
      }
      next();
    },
    getDialogZIndex() {
      return parseInt(_.get(this, '$refs.dialog.$el.style.zIndex'), 10);
    },
    async updateDrag() {
      if (!this.dragable) {
        return;
      }
      let dialogElement = _.get(this, "$refs.dialog.$el");
      if (!dialogElement) {
        await new Promise(resolve => this.$nextTick(resolve));
        dialogElement = _.get(this, "$refs.dialog.$el");
        if (!dialogElement) {
          this.windowDragable.destroy();
          return;
        }
      }
      let containerElement = dialogElement.querySelector(".el-dialog");
      let headerElement = dialogElement.querySelector(
        ".el-dialog__header"
      );

      if (this.windowDragable.dragElement !== dialogElement) {
        this.windowDragable.init({
          dragElement: headerElement,
          onUpdate: ({
            offsetX,
            offsetY
          }) => {
            containerElement.style.transform = `translate(${
                offsetX
            }px, ${offsetY}px)`;
            this.lastWindowOffset = {
                offsetX,
                offsetY
            };
          },
          initPosition: this.lastWindowOffset
        });
      }
      headerElement.style.cursor = "move";
      if (dialogElement.clientWidth >= containerElement.clientWidth) {
        dialogElement.style.overflowX = "hidden";
      }
    },
    resizeMinimize() {
      this.visible = true;
      this.minimizeSign = false;
    },
    closeMinimize() {
      this.minimizeSign = false;
      this.close();
    },
    async updateMinimize() {
      if (!this.minimizable) {
        return;
      }

      let dialogElement = _.get(this, "$refs.dialog.$el");
      if (!dialogElement) {
        await new Promise(resolve => this.$nextTick(resolve));
        dialogElement = _.get(this, "$refs.dialog.$el");
        if (!dialogElement) {
          this.minimizeDragable.destroy();
          return;
        }
      }
      let containerElement = dialogElement.querySelector(".el-dialog");
      let headerElement = dialogElement.querySelector(
        ".el-dialog__header"
      );

      let minimizeButton = headerElement.querySelector(".minimizeButton");

      if(!minimizeButton) {
        minimizeButton = document.createElement('div');
        minimizeButton.className = 'minimizeButton el-icon-minus';
        headerElement.appendChild(minimizeButton);
        minimizeButton.onclick = (event) => {

          this.minimizeSign = true;
          return event.stopPropagation()
        };
      }

      if(!this.minimizeSign) {
        return;
      }

      let minimizeBlockElement = this.$refs.minimizeBlock;
      if (!minimizeBlockElement) {
        await new Promise(resolve => this.$nextTick(resolve));
        minimizeBlockElement = _.get(this, "$refs.minimizeBlock");
        if (!minimizeBlockElement) {
          this.minimizeDragable.destroy();
          return;
        }
      }


      if (this.minimizeDragable.dragElement !== minimizeBlockElement) {
        this.minimizeDragable.init({
          dragElement: minimizeBlockElement,
          onUpdate: ({
            offsetX,
            offsetY
          }) => {
            minimizeBlockElement.style.transform = `translate(${
                offsetX
            }px, ${offsetY}px)`;
            this.lastMinimizeOffset = {
                offsetX,
                offsetY
            };
          },
          initPosition: this.lastMinimizeOffset
        });
      }
      // this.minimizeDragable.emitOffset();
    }
  }
};
</script>

<style scoped lang="scss">
.com-height {
    height: 75vh;
}
.minimizeBlock {
  position: fixed;
  left: 20px;
  bottom: 20px;
  background-color: #273a5b;
  padding: 10px;
  min-width: 100px;
  padding-right: 50px;
  border-radius: 4px;
  color: #fff;
  max-width: 100px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  z-index: 1000;
  cursor: move;

  .minimize-button {
    position: absolute;
    top: 13px;
    right: 5px;
    cursor: pointer;
  }
}
</style>

<style lang="scss">
.newDialogClass {
  border-radius: 3px !important;
  .el-dialog__header {
    padding: 7px 10px;
    border-radius: 3px 3px 0 0 !important;
    // background: linear-gradient(to right, #4485ce, #2360ad);
    text-align: center;
    .el-dialog__title {
      font-size: 14px;
      line-height: 2;
      font-weight: 700;
      // color: #fff;
      margin-left: 10px;
    }
    .el-dialog__headerbtn {
      position: absolute;
      top: 13px;
      right: 20px;
      padding: 0;
      background: transparent;
      border: none;
      outline: none;
      cursor: pointer;
      font-size: 16px;
    }
  }
  .el-dialog__body {
    //    padding: 20px 20px 20px 10px;
  }
}
.el-dialog__header {
  .minimizeButton {
    position: absolute;
    top: 24px;
    right: 60px;
    padding: 0;
    background: transparent;
    border: none;
    outline: none;
    cursor: pointer;
    font-size: 16px;
    color: #c3c3c3;
  }
}
</style>
